package it.unisannio.lesim.fsm;

import it.unisannio.lesim.fsm.exception.UnrecognizedTokenException;

/**
 *
 * @author Marco Calisti
 * @author Antonio Cuomo
 * @author Rocco Mazzeo
 * @author Francesco Pacilio
 * 
 */

public class ActionTokenizer {
    
    public static final int NOT_STARTED = 0;
    public static final int END_REACHED = 1;
    public static final int SAVE_FIELD_COMMAND = 2;
    public static final int SAVE_TIME_COMMAND = 3;
    public static final int COMMAND_SEPARATOR = 4;
    public static final int LEFT_SQUARE_PAR = 5;
    public static final int RIGHT_SQUARE_PAR = 6;
    public static final int CONSTANT_VALUE = 7;
    public static final int STRING = 8;
    public static final int STRING_SEPARATOR = 9;
    
    private String expression;
    private int kind;
    private String lexeme;
    
    public ActionTokenizer(String expression){
        this.expression= expression.trim();
        this.kind=NOT_STARTED;
        this.lexeme=expression;
    }
    
    public void consumeToken() throws UnrecognizedTokenException{
        if(expression.length()==0){
            kind=END_REACHED;
            lexeme="";
            return;
        }
        
        char firstChar=expression.charAt(0);
        //Handle single char tokens
        switch(firstChar){
            case '[' :    kind = LEFT_SQUARE_PAR; lexeme = expression.substring(0, 1); expression = expression.substring(1).trim(); return;
            case ']' :    kind = RIGHT_SQUARE_PAR; lexeme = expression.substring(0, 1); expression = expression.substring(1).trim(); return;
            case ';'  :   kind = COMMAND_SEPARATOR; lexeme = expression.substring(0, 1); expression = expression.substring(1).trim(); return;
            case ','  :   kind = STRING_SEPARATOR; lexeme = expression.substring(0, 1); expression = expression.substring(1).trim(); return;
            case '\'' :   kind = CONSTANT_VALUE; expression=expression.substring(1); handleDelimitedSequence('\''); return;
            case '\"' :   kind = STRING; expression=expression.substring(1); handleDelimitedSequence('\"'); return;
        }
        
        if(expression.startsWith("saveField")){
            kind = SAVE_FIELD_COMMAND;
            lexeme = expression.substring(0, "saveField".length());
            expression = expression.substring("saveField".length()).trim();
        
        } 
        else if(expression.startsWith("saveTime")){
            kind = SAVE_TIME_COMMAND;
            lexeme = expression.substring(0, "saveTime".length());
            expression = expression.substring("saveTime".length()).trim();
        
        }
        else
            throw new UnrecognizedTokenException();
    }
    
    private void handleDelimitedSequence(char delimiter) throws UnrecognizedTokenException {
       int closingIndex= expression.indexOf(delimiter);
       if(closingIndex==-1)
           throw new UnrecognizedTokenException();
       
       lexeme = expression.substring(0, closingIndex);
       expression = expression.substring(closingIndex+1);
    }
    
    public int lastTokenType(){
        return kind;
    }
    
    public String lastLexeme(){
        return lexeme;
    }
    
}
